Trò chơi Tic-Tac-Toe, game đánh caro full source code
- PhotonView.cs
- PhotonNetwork /
- Plugins /
- Photon Unity Networking /
- Assets /
- project /
2 // <copyright file="PhotonView.cs" company="Exit Games GmbH">
3 // PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
4 // </copyright>
5 // <summary>
6 //
7 // </summary>
8 // <author>developer@exitgames.com</author>
9 // ----------------------------------------------------------------------------
10
11 using System;
12 using UnityEngine;
13 using System.Reflection;
14 using System.Collections.Generic;
15 using ExitGames.Client.Photon;
16
17 #if UNITY_EDITOR
18 using UnityEditor;
19 #endif
20
21
22 public enum ViewSynchronization { Off, ReliableDeltaCompressed, Unreliable, UnreliableOnChange }
23 public enum OnSerializeTransform { OnlyPosition, OnlyRotation, OnlyScale, PositionAndRotation, All }
24 public enum OnSerializeRigidBody { OnlyVelocity, OnlyAngularVelocity, All }
25
26 /// <summary>
27 /// Options to define how Ownership Transfer is handled per PhotonView.
28 /// </summary>
29 /// <remarks>
30 /// This setting affects how RequestOwnership and TransferOwnership work at runtime.
31 /// </remarks>
32 public enum OwnershipOption
33 {
34 /// <summary>
35 /// Ownership is fixed. Instantiated objects stick with their creator, scene objects always belong to the Master Client.
36 /// </summary>
37 Fixed,
38 /// <summary>
39 /// Ownership can be taken away from the current owner who can't object.
40 /// </summary>
41 Takeover,
42 /// <summary>
43 /// Ownership can be requested with PhotonView.RequestOwnership but the current owner has to agree to give up ownership.
44 /// </summary>
45 /// <remarks>The current owner has to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.</remarks>
46 Request
47 }
48
49
50 /// <summary>
51 /// PUN's NetworkView replacement class for networking. Use it like a NetworkView.
52 /// </summary>
53 /// \ingroup publicApi
54 [AddComponentMenu("Photon Networking/Photon View &v")]
55 public class PhotonView : Photon.MonoBehaviour
56 {
57 #if UNITY_EDITOR
58 [ContextMenu("Open PUN Wizard")]
59 void OpenPunWizard()
60 {
61 EditorApplication.ExecuteMenuItem("Window/Photon Unity Networking");
62 }
63 #endif
64
65 public int ownerId;
66
67 public int group = 0;
68
69 protected internal bool mixedModeIsReliable = false;
70
71 // NOTE: this is now an integer because unity won't serialize short (needed for instantiation). we SEND only a short though!
72 // NOTE: prefabs have a prefixBackup of -1. this is replaced with any currentLevelPrefix that's used at runtime. instantiated GOs get their prefix set pre-instantiation (so those are not -1 anymore)
73 public int prefix
74 {
75 get
76 {
77 if (this.prefixBackup == -1 && PhotonNetwork.networkingPeer != null)
78 {
79 this.prefixBackup = PhotonNetwork.networkingPeer.currentLevelPrefix;
80 }
81
82 return this.prefixBackup;
83 }
84 set { this.prefixBackup = value; }
85 }
86
87 // this field is serialized by unity. that means it is copied when instantiating a persistent obj into the scene
88 public int prefixBackup = -1;
89
90 /// <summary>
91 /// This is the instantiationData that was passed when calling PhotonNetwork.Instantiate* (if that was used to spawn this prefab)
92 /// </summary>
93 public object[] instantiationData
94 {
95 get
96 {
97 if (!this.didAwake)
98 {
99 // even though viewID and instantiationID are setup before the GO goes live, this data can't be set. as workaround: fetch it if needed
100 this.instantiationDataField = PhotonNetwork.networkingPeer.FetchInstantiationData(this.instantiationId);
101 }
102 return this.instantiationDataField;
103 }
104 set { this.instantiationDataField = value; }
105 }
106
107 private object[] instantiationDataField;
108
109 /// <summary>
110 /// For internal use only, don't use
111 /// </summary>
112 protected internal object[] lastOnSerializeDataSent = null;
113
114 /// <summary>
115 /// For internal use only, don't use
116 /// </summary>
117 protected internal object[] lastOnSerializeDataReceived = null;
118
119 public Component observed;
120
121 public ViewSynchronization synchronization;
122
123 public OnSerializeTransform onSerializeTransformOption = OnSerializeTransform.PositionAndRotation;
124
125 public OnSerializeRigidBody onSerializeRigidBodyOption = OnSerializeRigidBody.All;
126
127 /// <summary>Defines if ownership of this PhotonView is fixed, can be requested or simply taken.</summary>
128 /// <remarks>
129 /// Note that you can't edit this value at runtime.
130 /// The options are described in enum OwnershipOption.
131 /// The current owner has to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
132 /// </remarks>
133 public OwnershipOption ownershipTransfer = OwnershipOption.Fixed;
134
135 public List<Component> ObservedComponents;
136 Dictionary<Component, MethodInfo> m_OnSerializeMethodInfos = new Dictionary<Component, MethodInfo>();
137
138 //These fields are only used in the CustomEditor for this script and would trigger a
139 //"this variable is never used" warning, which I am suppressing here
140 #pragma warning disable 0414
141 [SerializeField]
142 bool ObservedComponentsFoldoutOpen = true;
143 #pragma warning restore 0414
144
145 [SerializeField]
146 private int viewIdField = 0;
147
148 /// <summary>
149 /// The ID of the PhotonView. Identifies it in a networked game (per room).
150 /// </summary>
151 /// <remarks>See: [Network Instantiation](@ref instantiateManual)</remarks>
152 public int viewID
153 {
154 get { return this.viewIdField; }
155 set
156 {
157 // if ID was 0 for an awakened PhotonView, the view should add itself into the networkingPeer.photonViewList after setup
158 bool viewMustRegister = this.didAwake && this.viewIdField == 0;
159
160 // TODO: decide if a viewID can be changed once it wasn't 0. most likely that is not a good idea
161 // check if this view is in networkingPeer.photonViewList and UPDATE said list (so we don't keep the old viewID with a reference to this object)
162 // PhotonNetwork.networkingPeer.RemovePhotonView(this, true);
163
164 this.ownerId = value / PhotonNetwork.MAX_VIEW_IDS;
165
166 this.viewIdField = value;
167
168 if (viewMustRegister)
169 {
170 PhotonNetwork.networkingPeer.RegisterPhotonView(this);
171 }
172 //Debug.Log("Set viewID: " + value + " -> owner: " + this.ownerId + " subId: " + this.subId);
173 }
174 }
175
176 public int instantiationId; // if the view was instantiated with a GO, this GO has a instantiationID (first view's viewID)
177
178 /// <summary>True if the PhotonView was loaded with the scene (game object) or instantiated with InstantiateSceneObject.</summary>
179 /// <remarks>
180 /// Scene objects are not owned by a particular player but belong to the scene. Thus they don't get destroyed when their
181 /// creator leaves the game and the current Master Client can control them (whoever that is).
182 /// The ownerId is 0 (player IDs are 1 and up).
183 /// </remarks>
184 public bool isSceneView
185 {
186 get { return this.CreatorActorNr == 0; }
187 }
188
189 /// <summary>
190 /// The owner of a PhotonView is the player who created the GameObject with that view. Objects in the scene don't have an owner.
191 /// </summary>
192 /// <remarks>
193 /// The owner/controller of a PhotonView is also the client which sends position updates of the GameObject.
194 ///
195 /// Ownership can be transferred to another player with PhotonView.TransferOwnership or any player can request
196 /// ownership by calling the PhotonView's RequestOwnership method.
197 /// The current owner has to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
198 /// </remarks>
199 public PhotonPlayer owner
200 {
201 get { return PhotonPlayer.Find(this.ownerId); }
202 }
203
204 public int OwnerActorNr
205 {
206 get { return this.ownerId; }
207 }
208
209 public bool isOwnerActive
210 {
211 get { return this.ownerId != 0 && PhotonNetwork.networkingPeer.mActors.ContainsKey(this.ownerId); }
212 }
213
214 public int CreatorActorNr
215 {
216 get { return this.viewIdField / PhotonNetwork.MAX_VIEW_IDS; }
217 }
218
219 /// <summary>
220 /// True if the PhotonView is "mine" and can be controlled by this client.
221 /// </summary>
222 /// <remarks>
223 /// PUN has an ownership concept that defines who can control and destroy each PhotonView.
224 /// True in case the owner matches the local PhotonPlayer.
225 /// True if this is a scene photonview on the Master client.
226 /// </remarks>
227 public bool isMine
228 {
229 get
230 {
231 return (this.ownerId == PhotonNetwork.player.ID) || (!this.isOwnerActive && PhotonNetwork.isMasterClient);
232 }
233 }
234
235 protected internal bool didAwake;
236
237 [SerializeField]
238 protected internal bool isRuntimeInstantiated;
239
240 protected internal bool destroyedByPhotonNetworkOrQuit;
241
242 /// <summary>Called by Unity on start of the application and does a setup the PhotonView.</summary>
243 protected internal void Awake()
244 {
245 // registration might be too late when some script (on this GO) searches this view BUT GetPhotonView() can search ALL in that case
246 PhotonNetwork.networkingPeer.RegisterPhotonView(this);
247
248 this.instantiationDataField = PhotonNetwork.networkingPeer.FetchInstantiationData(this.instantiationId);
249 this.didAwake = true;
250 }
251
252 /// <summary>
253 /// Depending on the PhotonView's ownershipTransfer setting, any client can request to become owner of the PhotonView.
254 /// </summary>
255 /// <remarks>
256 /// Requesting ownership can give you control over a PhotonView, if the ownershipTransfer setting allows that.
257 /// The current owner might have to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
258 ///
259 /// The owner/controller of a PhotonView is also the client which sends position updates of the GameObject.
260 /// </remarks>
261 public void RequestOwnership()
262 {
263 PhotonNetwork.networkingPeer.RequestOwnership(this.viewID, this.ownerId);
264 }
265
266 /// <summary>
267 /// Transfers the ownership of this PhotonView (and GameObject) to another player.
268 /// </summary>
269 /// <remarks>
270 /// The owner/controller of a PhotonView is also the client which sends position updates of the GameObject.
271 /// </remarks>
272 public void TransferOwnership(PhotonPlayer newOwner)
273 {
274 this.TransferOwnership(newOwner.ID);
275 }
276
277 /// <summary>
278 /// Transfers the ownership of this PhotonView (and GameObject) to another player.
279 /// </summary>
280 /// <remarks>
281 /// The owner/controller of a PhotonView is also the client which sends position updates of the GameObject.
282 /// </remarks>
283 public void TransferOwnership(int newOwnerId)
284 {
285 PhotonNetwork.networkingPeer.TransferOwnership(this.viewID, newOwnerId);
286 this.ownerId = newOwnerId; // immediately switch ownership locally, to avoid more updates sent from this client.
287 }
288
289
290 protected internal void OnApplicationQuit()
291 {
292 destroyedByPhotonNetworkOrQuit = true; // on stop-playing its ok Destroy is being called directly (not by PN.Destroy())
293 }
294
295 protected internal void OnDestroy()
296 {
297 if (!this.destroyedByPhotonNetworkOrQuit)
298 {
299 PhotonNetwork.networkingPeer.LocalCleanPhotonView(this);
300 }
301
302 if (!this.destroyedByPhotonNetworkOrQuit && !Application.isLoadingLevel)
303 {
304 if (this.instantiationId > 0)
305 {
306 // if this viewID was not manually assigned (and we're not shutting down or loading a level), you should use PhotonNetwork.Destroy() to get rid of GOs with PhotonViews
307 Debug.LogError("OnDestroy() seems to be called without PhotonNetwork.Destroy()?! GameObject: " + this.gameObject + " Application.isLoadingLevel: " + Application.isLoadingLevel);
308 }
309 else
310 {
311 // this seems to be a manually instantiated PV. if it's local, we could warn if the ID is not in the allocated-list
312 if (this.viewID <= 0)
313 {
314 Debug.LogWarning(string.Format("OnDestroy manually allocated PhotonView {0}. The viewID is 0. Was it ever (manually) set?", this));
315 }
316 else if (this.isMine && !PhotonNetwork.manuallyAllocatedViewIds.Contains(this.viewID))
317 {
318 Debug.LogWarning(string.Format("OnDestroy manually allocated PhotonView {0}. The viewID is local (isMine) but not in manuallyAllocatedViewIds list. Use UnAllocateViewID() after you destroyed the PV.", this));
319 }
320 }
321 }
322 }
323
324 private MethodInfo OnSerializeMethodInfo;
325
326 private bool failedToFindOnSerialize;
327
328 public void SerializeView( PhotonStream stream, PhotonMessageInfo info )
329 {
330 SerializeComponent( observed, stream, info );
331
332 for( int i = 0; i < ObservedComponents.Count; ++i )
333 {
334 SerializeComponent( ObservedComponents[ i ], stream, info );
335 }
336 }
337
338 public void DeserializeView( PhotonStream stream, PhotonMessageInfo info )
339 {
340 DeserializeComponent( observed, stream, info );
341
342 for( int i = 0; i < ObservedComponents.Count; ++i )
343 {
344 DeserializeComponent( ObservedComponents[ i ], stream, info );
345 }
346 }
347
348 internal protected void DeserializeComponent( Component component, PhotonStream stream, PhotonMessageInfo info )
349 {
350 if( component == null )
351 {
352 return;
353 }
354
355 // Use incoming data according to observed type
356 if( component is MonoBehaviour )
357 {
358 ExecuteComponentOnSerialize( component, stream, info );
359 }
360 else if( component is Transform )
361 {
362 Transform trans = (Transform)component;
363
364 switch( onSerializeTransformOption )
365 {
366 case OnSerializeTransform.All:
367 trans.localPosition = (Vector3)stream.ReceiveNext();
368 trans.localRotation = (Quaternion)stream.ReceiveNext();
369 trans.localScale = (Vector3)stream.ReceiveNext();
370 break;
371 case OnSerializeTransform.OnlyPosition:
372 trans.localPosition = (Vector3)stream.ReceiveNext();
373 break;
374 case OnSerializeTransform.OnlyRotation:
375 trans.localRotation = (Quaternion)stream.ReceiveNext();
376 break;
377 case OnSerializeTransform.OnlyScale:
378 trans.localScale = (Vector3)stream.ReceiveNext();
379 break;
380 case OnSerializeTransform.PositionAndRotation:
381 trans.localPosition = (Vector3)stream.ReceiveNext();
382 trans.localRotation = (Quaternion)stream.ReceiveNext();
383 break;
384 }
385 }
386 else if( component is Rigidbody )
387 {
388 Rigidbody rigidB = (Rigidbody)component;
389
390 switch( onSerializeRigidBodyOption )
391 {
392 case OnSerializeRigidBody.All:
393 rigidB.velocity = (Vector3)stream.ReceiveNext();
394 rigidB.angularVelocity = (Vector3)stream.ReceiveNext();
395 break;
396 case OnSerializeRigidBody.OnlyAngularVelocity:
397 rigidB.angularVelocity = (Vector3)stream.ReceiveNext();
398 break;
399 case OnSerializeRigidBody.OnlyVelocity:
400 rigidB.velocity = (Vector3)stream.ReceiveNext();
401 break;
402 }
403 }
404 else if( component is Rigidbody2D )
405 {
406 Rigidbody2D rigidB = (Rigidbody2D)component;
407
408 switch( onSerializeRigidBodyOption )
409 {
410 case OnSerializeRigidBody.All:
411 rigidB.velocity = (Vector2)stream.ReceiveNext();
412 rigidB.angularVelocity = (float)stream.ReceiveNext();
413 break;
414 case OnSerializeRigidBody.OnlyAngularVelocity:
415 rigidB.angularVelocity = (float)stream.ReceiveNext();
416 break;
417 case OnSerializeRigidBody.OnlyVelocity:
418 rigidB.velocity = (Vector2)stream.ReceiveNext();
419 break;
420 }
421 }
422 else
423 {
424 Debug.LogError( "Type of observed is unknown when receiving." );
425 }
426 }
427
428 internal protected void SerializeComponent( Component component, PhotonStream stream, PhotonMessageInfo info )
429 {
430 if( component == null )
431 {
432 return;
433 }
434
435 if( component is MonoBehaviour )
436 {
437 ExecuteComponentOnSerialize( component, stream, info );
438 }
439 else if( component is Transform )
440 {
441 Transform trans = (Transform)component;
442
443 switch( onSerializeTransformOption )
444 {
445 case OnSerializeTransform.All:
446 stream.SendNext( trans.localPosition );
447 stream.SendNext( trans.localRotation );
448 stream.SendNext( trans.localScale );
449 break;
450 case OnSerializeTransform.OnlyPosition:
451 stream.SendNext( trans.localPosition );
452 break;
453 case OnSerializeTransform.OnlyRotation:
454 stream.SendNext( trans.localRotation );
455 break;
456 case OnSerializeTransform.OnlyScale:
457 stream.SendNext( trans.localScale );
458 break;
459 case OnSerializeTransform.PositionAndRotation:
460 stream.SendNext( trans.localPosition );
461 stream.SendNext( trans.localRotation );
462 break;
463 }
464 }
465 else if( component is Rigidbody )
466 {
467 Rigidbody rigidB = (Rigidbody)component;
468
469 switch( onSerializeRigidBodyOption )
470 {
471 case OnSerializeRigidBody.All:
472 stream.SendNext( rigidB.velocity );
473 stream.SendNext( rigidB.angularVelocity );
474 break;
475 case OnSerializeRigidBody.OnlyAngularVelocity:
476 stream.SendNext( rigidB.angularVelocity );
477 break;
478 case OnSerializeRigidBody.OnlyVelocity:
479 stream.SendNext( rigidB.velocity );
480 break;
481 }
482 }
483 else if( component is Rigidbody2D )
484 {
485 Rigidbody2D rigidB = (Rigidbody2D)component;
486
487 switch( onSerializeRigidBodyOption )
488 {
489 case OnSerializeRigidBody.All:
490 stream.SendNext( rigidB.velocity );
491 stream.SendNext( rigidB.angularVelocity );
492 break;
493 case OnSerializeRigidBody.OnlyAngularVelocity:
494 stream.SendNext( rigidB.angularVelocity );
495 break;
496 case OnSerializeRigidBody.OnlyVelocity:
497 stream.SendNext( rigidB.velocity );
498 break;
499 }
500 }
501 else
502 {
503 Debug.LogError( "Observed type is not serializable: " + component.GetType() );
504 }
505 }
506
507 internal protected void ExecuteComponentOnSerialize( Component component, PhotonStream stream, PhotonMessageInfo info )
508 {
509 if( component != null )
510 {
511 if( m_OnSerializeMethodInfos.ContainsKey( component ) == false )
512 {
513 MethodInfo newMethod = null;
514 bool foundMethod = NetworkingPeer.GetMethod( component as MonoBehaviour, PhotonNetworkingMessage.OnPhotonSerializeView.ToString(), out newMethod );
515
516 if( foundMethod == false )
517 {
518 Debug.LogError( "The observed monobehaviour (" + component.name + ") of this PhotonView does not implement OnPhotonSerializeView()!" );
519 newMethod = null;
520 }
521
522 m_OnSerializeMethodInfos.Add( component, newMethod );
523 }
524
525 if( m_OnSerializeMethodInfos[ component ] != null )
526 {
527 m_OnSerializeMethodInfos[ component ].Invoke( component, new object[] { stream, info } );
528 }
529 }
530 }
531
532 /// <summary>
533 /// Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
534 /// </summary>
535 /// <remarks>
536 /// [Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
537 /// It enables you to make every client in a room call a specific method.
538 ///
539 /// RPC calls can target "All" or the "Others".
540 /// Usually, the target "All" gets executed locally immediately after sending the RPC.
541 /// The "*ViaServer" options send the RPC to the server and execute it on this client when it's sent back.
542 /// Of course, calls are affected by this client's lag and that of remote clients.
543 ///
544 /// Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
545 /// originating client.
546 ///
547 /// See: [Remote Procedure Calls](@ref rpcManual).
548 /// </remarks>
549 /// <param name="methodName">The name of a fitting method that was has the RPC attribute.</param>
550 /// <param name="target">The group of targets and the way the RPC gets sent.</param>
551 /// <param name="parameters">The parameters that the RPC method has (must fit this call!).</param>
552 public void RPC(string methodName, PhotonTargets target, params object[] parameters)
553 {
554 RpcSecure(methodName, target, false, parameters);
555 }
556
557 /// <summary>
558 /// Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
559 /// </summary>
560 /// <remarks>
561 /// [Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
562 /// It enables you to make every client in a room call a specific method.
563 ///
564 /// RPC calls can target "All" or the "Others".
565 /// Usually, the target "All" gets executed locally immediately after sending the RPC.
566 /// The "*ViaServer" options send the RPC to the server and execute it on this client when it's sent back.
567 /// Of course, calls are affected by this client's lag and that of remote clients.
568 ///
569 /// Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
570 /// originating client.
571 ///
572 /// See: [Remote Procedure Calls](@ref rpcManual).
573 /// </remarks>
574 ///<param name="methodName">The name of a fitting method that was has the RPC attribute.</param>
575 ///<param name="target">The group of targets and the way the RPC gets sent.</param>
576 ///<param name="encrypt"> </param>
577 ///<param name="parameters">The parameters that the RPC method has (must fit this call!).</param>
578 public void RpcSecure(string methodName, PhotonTargets target, bool encrypt, params object[] parameters)
579 {
580 if(PhotonNetwork.networkingPeer.hasSwitchedMC && target == PhotonTargets.MasterClient)
581 {
582 PhotonNetwork.RPC(this, methodName, PhotonNetwork.masterClient, encrypt, parameters);
583 }
584 else
585 {
586 PhotonNetwork.RPC(this, methodName, target, encrypt, parameters);
587 }
588 }
589
590 /// <summary>
591 /// Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
592 /// </summary>
593 /// <remarks>
594 /// [Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
595 /// It enables you to make every client in a room call a specific method.
596 ///
597 /// This method allows you to make an RPC calls on a specific player's client.
598 /// Of course, calls are affected by this client's lag and that of remote clients.
599 ///
600 /// Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
601 /// originating client.
602 ///
603 /// See: [Remote Procedure Calls](@ref rpcManual).
604 /// </remarks>
605 /// <param name="methodName">The name of a fitting method that was has the RPC attribute.</param>
606 /// <param name="targetPlayer">The group of targets and the way the RPC gets sent.</param>
607 /// <param name="parameters">The parameters that the RPC method has (must fit this call!).</param>
608 public void RPC(string methodName, PhotonPlayer targetPlayer, params object[] parameters)
609 {
610 PhotonNetwork.RPC(this, methodName, targetPlayer, false, parameters);
611 }
612
613 /// <summary>
614 /// Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
615 /// </summary>
616 /// <remarks>
617 /// [Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
618 /// It enables you to make every client in a room call a specific method.
619 ///
620 /// This method allows you to make an RPC calls on a specific player's client.
621 /// Of course, calls are affected by this client's lag and that of remote clients.
622 ///
623 /// Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
624 /// originating client.
625 ///
626 /// See: [Remote Procedure Calls](@ref rpcManual).
627 /// </remarks>
628 ///<param name="methodName">The name of a fitting method that was has the RPC attribute.</param>
629 ///<param name="targetPlayer">The group of targets and the way the RPC gets sent.</param>
630 ///<param name="encrypt"> </param>
631 ///<param name="parameters">The parameters that the RPC method has (must fit this call!).</param>
632 public void RpcSecure(string methodName, PhotonPlayer targetPlayer, bool encrypt, params object[] parameters)
633 {
634 PhotonNetwork.RPC(this, methodName, targetPlayer, encrypt, parameters);
635 }
636
637 public static PhotonView Get(Component component)
638 {
639 return component.GetComponent<PhotonView>();
640 }
641
642 public static PhotonView Get(GameObject gameObj)
643 {
644 return gameObj.GetComponent<PhotonView>();
645 }
646
647 public static PhotonView Find(int viewID)
648 {
649 return PhotonNetwork.networkingPeer.GetPhotonView(viewID);
650 }
651
652 public override string ToString()
653 {
654 return string.Format("View ({3}){0} on {1} {2}", this.viewID, (this.gameObject != null) ? this.gameObject.name : "GO==null", (this.isSceneView) ? "(scene)" : string.Empty, this.prefix);
655 }
656 }
----------------------------------------------------------------------------
PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
----------------------------------------------------------------------------
Options to define how Ownership Transfer is handled per PhotonView.
This setting affects how RequestOwnership and TransferOwnership work at runtime.
Ownership is fixed. Instantiated objects stick with their creator, scene objects always belong to the Master Client.
Ownership can be taken away from the current owner who can't object.
Ownership can be requested with PhotonView.RequestOwnership but the current owner has to agree to give up ownership.
PUN's NetworkView replacement class for networking. Use it like a NetworkView.
\ingroup publicApi
NOTE: this is now an integer because unity won't serialize short (needed for instantiation). we SEND only a short though!
NOTE: prefabs have a prefixBackup of -1. this is replaced with any currentLevelPrefix that's used at runtime. instantiated GOs get their prefix set pre-instantiation (so those are not -1 anymore)
this field is serialized by unity. that means it is copied when instantiating a persistent obj into the scene
This is the instantiationData that was passed when calling PhotonNetwork.Instantiate* (if that was used to spawn this prefab)
even though viewID and instantiationID are setup before the GO goes live, this data can't be set. as workaround: fetch it if needed
For internal use only, don't use
For internal use only, don't use
Note that you can't edit this value at runtime.
The options are described in enum OwnershipOption.
The current owner has to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
These fields are only used in the CustomEditor for this script and would trigger a
"this variable is never used" warning, which I am suppressing here
The ID of the PhotonView. Identifies it in a networked game (per room).
if ID was 0 for an awakened PhotonView, the view should add itself into the networkingPeer.photonViewList after setup
TODO: decide if a viewID can be changed once it wasn't 0. most likely that is not a good idea
check if this view is in networkingPeer.photonViewList and UPDATE said list (so we don't keep the old viewID with a reference to this object)
PhotonNetwork.networkingPeer.RemovePhotonView(this, true);
Debug.Log("Set viewID: " + value + " -> owner: " + this.ownerId + " subId: " + this.subId);
public int instantiationId; if the view was instantiated with a GO, this GO has a instantiationID (first view's viewID)
Scene objects are not owned by a particular player but belong to the scene. Thus they don't get destroyed when their
creator leaves the game and the current Master Client can control them (whoever that is).
The ownerId is 0 (player IDs are 1 and up).
The owner of a PhotonView is the player who created the GameObject with that view. Objects in the scene don't have an owner.
The ownercontroller of a PhotonView is also the client which sends position updates of the GameObject.
Ownership can be transferred to another player with PhotonView.TransferOwnership or any player can request
ownership by calling the PhotonView's RequestOwnership method.
The current owner has to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
True if the PhotonView is "mine" and can be controlled by this client.
PUN has an ownership concept that defines who can control and destroy each PhotonView.
True in case the owner matches the local PhotonPlayer.
True if this is a scene photonview on the Master client.
registration might be too late when some script (on this GO) searches this view BUT GetPhotonView() can search ALL in that case
Depending on the PhotonView's ownershipTransfer setting, any client can request to become owner of the PhotonView.
Requesting ownership can give you control over a PhotonView, if the ownershipTransfer setting allows that.
The current owner might have to implement IPunCallbacks.OnOwnershipRequest to react to the ownership request.
The ownercontroller of a PhotonView is also the client which sends position updates of the GameObject.
Transfers the ownership of this PhotonView (and GameObject) to another player.
The ownercontroller of a PhotonView is also the client which sends position updates of the GameObject.
Transfers the ownership of this PhotonView (and GameObject) to another player.
The ownercontroller of a PhotonView is also the client which sends position updates of the GameObject.
this.ownerId = newOwnerId; immediately switch ownership locally, to avoid more updates sent from this client.
destroyedByPhotonNetworkOrQuit = true; on stop-playing its ok Destroy is being called directly (not by PN.Destroy())
if this viewID was not manually assigned (and we're not shutting down or loading a level), you should use PhotonNetwork.Destroy() to get rid of GOs with PhotonViews
this seems to be a manually instantiated PV. if it's local, we could warn if the ID is not in the allocated-list
Use incoming data according to observed type
Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
[Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
It enables you to make every client in a room call a specific method.
RPC calls can target "All" or the "Others".
Usually, the target "All" gets executed locally immediately after sending the RPC.
The "*ViaServer" options send the RPC to the server and execute it on this client when it's sent back.
Of course, calls are affected by this client's lag and that of remote clients.
Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
originating client.
See: [Remote Procedure Calls](@ref rpcManual).
The name of a fitting method that was has the RPC attribute.
The group of targets and the way the RPC gets sent.
The parameters that the RPC method has (must fit this call!).
Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
[Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
It enables you to make every client in a room call a specific method.
RPC calls can target "All" or the "Others".
Usually, the target "All" gets executed locally immediately after sending the RPC.
The "*ViaServer" options send the RPC to the server and execute it on this client when it's sent back.
Of course, calls are affected by this client's lag and that of remote clients.
Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
originating client.
See: [Remote Procedure Calls](@ref rpcManual).
The name of a fitting method that was has the RPC attribute.
The group of targets and the way the RPC gets sent.
The parameters that the RPC method has (must fit this call!).
Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
[Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
It enables you to make every client in a room call a specific method.
This method allows you to make an RPC calls on a specific player's client.
Of course, calls are affected by this client's lag and that of remote clients.
Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
originating client.
See: [Remote Procedure Calls](@ref rpcManual).
The name of a fitting method that was has the RPC attribute.
The group of targets and the way the RPC gets sent.
The parameters that the RPC method has (must fit this call!).
Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client).
[Remote Procedure Calls](@ref rpcManual) are an essential tool in making multiplayer games with PUN.
It enables you to make every client in a room call a specific method.
This method allows you to make an RPC calls on a specific player's client.
Of course, calls are affected by this client's lag and that of remote clients.
Each call automatically is routed to the same PhotonView (and GameObject) that was used on the
originating client.
See: [Remote Procedure Calls](@ref rpcManual).
The name of a fitting method that was has the RPC attribute.
The group of targets and the way the RPC gets sent.
The parameters that the RPC method has (must fit this call!).